/*
    This file is part of Epoch <http://code.google.com/p/epoch/>.
    
    Copyright (C) 2011  Adam Meily <meily.adam@gmail.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License along
    with this program; if not, write to the Free Software Foundation, Inc.,
    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/


#include "Certificate.h"

//const char Certificate::MagicNumber[] = { 0x0c, 0x06, 0x7d, 0x08 };
/*
Certificate::Certificate(QDataStream& stream)
{
    char buffer[64];
    int len;
    
    // get magic number
    len = stream.readRawData(buffer, 4);
    if(len < 4 || !checkMagicNum(buffer))
        throw BadCertificateException();
    
    
    // device
    len = stream.readRawData(buffer, 16);
    if(len < 16)
        throw BadCertificateException();
    m_deviceId = QByteArray::fromRawData(buffer, 16);
    
    // client
    len = stream.readRawData(buffer, 16);
    if(len < 16)
        throw BadCertificateException();
    m_clientKey = QByteArray::fromRawData(buffer, 16);
    
    // server
    len = stream.readRawData(buffer, 32);
    if(len < 32)
        throw BadCertificateException();
    m_serverKey = QByteArray::fromRawData(buffer, 32);
    
    
    char check;
    stream >> check;
    if(check != '<')
        throw BadCertificateException();
    
    QString uuidstr = stream.readLine(256);
    if(uuidstr.isNull())
        throw BadCertificateException();
    
    QString clientKey = stream.readLine(256);
    if(clientKey.isNull())
        throw BadCertificateException();
    
    QString serverKey = stream.readLine(256);
    if(serverKey.isNull())
        throw BadCertificateException();
    
    int len = serverKey.length();
    check = serverKey[len - 1];
    if(check != '>')
        throw BadCertificateException();
    
    serverKey = serverKey.left(len-1);
    
    if(serverKey > 64)
        throw BadCertificateException();
    pad(serverKey, 64);
    
    if(clientKey.length() > 32)
        throw BadCertificateException();
    pad(clientKey, 32);
    
    QUuid uuid(uuidstr);
    if(uuid.isNull())
        throw BadCertificateException();
    
    m_clientKey = QByteArray::fromHex(clientKey);
    m_serverKey = QByteArray::fromHex(serverKey);
    m_deviceUuid = uuid;
    
}
*/
    
Certificate::Certificate(const Certificate& other) : m_deviceKey(other.m_deviceKey),
                                                     m_serverKey(other.m_serverKey),
                                                     m_deviceUuid(other.m_deviceUuid)
{
}

Certificate::Certificate(const QByteArray& devUuid, const QByteArray& devKey,
                         const QByteArray& serverKey) : m_deviceUuid(devUuid),
                                                        m_deviceKey(devKey),
                                                        m_serverKey(serverKey)
{
}


Certificate::Certificate()
{

}

Certificate Certificate::fromHex(const QString& hex, const QByteArray& serverKey)
{
    QByteArray tmp = QByteArray::fromHex(hex.toUtf8());
    
    if(tmp.length() != 32)
        return Certificate();
    
    for(int i = 0; i < 32; i++)
        tmp[i] = tmp[i] ^ serverKey[i];
    
    return Certificate(tmp.left(16), tmp.right(16), serverKey);
}

bool Certificate::isNull() const
{
    return m_deviceKey.isEmpty() && m_deviceUuid.isEmpty() &&
           m_serverKey.isEmpty();
}



Certificate::~Certificate()
{
}

/*
bool Certificate::checkMagicNum(const char* input) const
{
    bool valid = true;
    for(int i = 0; i < 4 && valid; i++)
        valid = input[i] == MagicNumber[i];
    return valid;
}
*/

const QByteArray& Certificate::deviceKey() const
{
    return m_deviceKey;
}

const QByteArray& Certificate::deviceUuid() const
{
    return m_deviceUuid;
}

const QByteArray& Certificate::serverKey() const
{
    return m_serverKey;
}

Certificate& Certificate::operator=(const Certificate& other)
{
    m_deviceKey = other.m_deviceKey;
    m_serverKey = other.m_serverKey;
    m_deviceUuid = other.m_deviceUuid;
    return *this;
}

bool Certificate::operator==(const Certificate& other) const
{
    return m_deviceKey == other.m_deviceKey && m_serverKey == other.m_serverKey &&
           m_deviceUuid == other.m_deviceUuid;
}

QString Certificate::prepare() const
{
    QByteArray temp = m_deviceUuid + m_deviceKey;
    for(int i = 0; i < 32; i++)
        temp[i] = temp[i] ^ m_serverKey[i];
    
    return temp.toHex();
}


